package com.hliushi.domain;

import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;

/**
 * 电梯
 *
 * @author: hliushi
 * @date: 2023/2/18 22:08
 **/
public class Elevator {

    private List<ElevatorButton> buttons;

    /**
     * 如果电梯目前在 1L, 有人按下了 5L 向上, 之后又有人按下了 3L 电梯会怎么行动 ?
     * stop will {5, 3} Expected is : {3, 5}
     * <p>
     * Solution1: sort stop every time we add to it ->
     * <p>
     * Solution2: use priority queue instead of list 可以使用大小堆构建出来的数据结构 -> 优先队列
     * <p>
     * 如果电梯目前在 1L, 有人按下了 5L 向上, 之后又有人按下了 3L 向上, 紧接着这条电梯有被分配了一个 2L 向下的 request
     * 这条电梯如何行动?
     * <p>
     * stop will be {2, 3, 5} Expected is : {3, 5, 2}
     * <p>
     * Solution: keep 2 lists for different direction
     * #
     * 同方向 > 静止 > 反方向
     * <p>
     * what if I want to apply different ways to handle external requests during different time of day?
     * # 不同时间应用不同的方式
     * Solution1: if - else
     * Solution2: Strategy-Mode
     */
    private Queue<Integer> upStops;
    private Queue<Integer> downStops;

    private volatile int currentLevel;

    private volatile Status status;

    private boolean gateOpen;

    private float weightLimit = 1300;

    public Elevator(List<ElevatorButton> buttons) {
        this.buttons = buttons;
        this.upStops = new PriorityQueue<>(10);
        this.downStops = new PriorityQueue<>(10);
        status = Status.IDLE;
        gateOpen = false;
    }


    /**
     * An elevator takes an external request, inserts in its stop list
     */
    public void handleExternalRequest(ExternalRequest request) {

    }

    /**
     * An elevator takes an internal request, determine if it's valid, inserts in its stop list
     */
    public void handleInternalRequest(InternalRequest request) {

    }


    /**
     * 如果判断一个 Internal request 是否为 valid
     * if elevator going up
     * .    requested level lower than currentLevel
     * .        invalid
     * <p>
     * if elevator going down
     * .    requested level higher than currentLevel
     * .        invalid
     */
    private boolean isRequestValid(InternalRequest request) {

        return false;
    }


    /**
     * use case: open gate
     */
    public void openGate() {

    }

    /**
     * use case: close gate
     */
    public void closeGate() {

    }

    /**
     * An elevator checks its current wight and compare with limit ot see if overweight
     */
    private float currentWeight() {
        return 0.0f;
    }


    public int getCurrentLevel() {
        return currentLevel;
    }

    public void setCurrentLevel(int currentLevel) {
        this.currentLevel = currentLevel;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public boolean isGateOpen() {
        return gateOpen;
    }

    public void setGateOpen(boolean gateOpen) {
        this.gateOpen = gateOpen;
    }
}
